package com.fintech.third.service.ocr;

import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.dragon.app.commons.dto.BankcardSaveDTO;
import com.dragon.web.commons.utils.ImageUtils;
import com.fintech.common.enums.CardTypeEnum;
import com.fintech.common.enums.InterfaceMethodEnum;
import com.fintech.common.enums.StateEnum;
import com.fintech.third.constant.Constants;
import com.fintech.third.model.ocr.IdCardDto;
import com.fintech.third.model.reqlog.IntDataQueryLog;
import com.fintech.third.service.reqlog.IntDataQueryLogService;
import com.marvels.common.enums.SexEnum;
import com.marvels.common.utils.MarvelsLogUtil;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.BankCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.BankCardOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;

/**
 * @author helichao
 * @Description 
 * @Date 2021/01/24 09:01:45
 */
@Service
public class CardOcrService {
	
	@Value("${tencentcloud.region}")
	private String region;
	
	@Value("${tencentcloud.secretId}")
	private String secretId;
	
	@Value("${tencentcloud.secretKey}")
	private String secretKey;
	
	@Autowired
	private IntDataQueryLogService intDataQueryLogService;
	
	public IdCardDto idCardOcr(File imageFile) {
		if(null==imageFile || !imageFile.exists()) {
			return null;
		}
		return idCardOcr(ImageUtils.imageToBase64(imageFile));
	}
	
	public BankcardSaveDTO bankCardOcr(File imageFile) {
		if(null==imageFile || !imageFile.exists()) {
			return null;
		}
		return bankCardOcr(ImageUtils.imageToBase64(imageFile));
	}
	
	public IdCardDto idCardOcr(String imageBase64) {
		if(StringUtils.isBlank(imageBase64)) {
			return null;
		}
		
		Map<String,String> cardMap = cardOcr(imageBase64, CardTypeEnum.ID_CARD.getCode());
		if(MapUtils.isEmpty(cardMap)) {
			return null;
		}
		
		IdCardDto dto = new IdCardDto();
		dto.setRealName(cardMap.get("Name"));
		dto.setIdentityCardNo(cardMap.get("IdNum"));
		dto.setAuthority(cardMap.get("Authority"));
		dto.setAddress(cardMap.get("Address"));
		dto.setNation(cardMap.get("Nation"));
		dto.setBirthday(cardMap.get("Birth"));
		if(StringUtils.isNotBlank(cardMap.get("ValidDate"))) {
			String vaildDateStr = cardMap.get("ValidDate");
			int index = StringUtils.indexOf(vaildDateStr, "-");
			if(-1 != index) {
				try {
					String spitStartDateStr = StringUtils.substring(vaildDateStr, 0, index);
					String spitEndDateStr = StringUtils.substring(vaildDateStr, 11);
					dto.setValidityfrom(StringUtils.replace(spitStartDateStr, ".", "-"));
					dto.setValidityto(StringUtils.replace(spitEndDateStr, ".", "-"));
				}catch(Exception ex) {
					MarvelsLogUtil.getInstance().error("CardOcrService.idCardOcr the ValidDate to Date error",ex);
				}
			}
		}
		if(StringUtils.isNotBlank(cardMap.get("Sex"))) {
			if(StringUtils.equals("男", cardMap.get("Sex"))) {
				dto.setSex(SexEnum.MALE.getCode());
			}else if(StringUtils.equals("女", cardMap.get("Sex"))) {
				dto.setSex(SexEnum.FEMALE.getCode());
			}
		}
		
		return dto;
	}
	
	public BankcardSaveDTO bankCardOcr(String imageBase64) {
		if(StringUtils.isBlank(imageBase64)) {
			return null;
		}
		Map<String,String> bankInfoMap = cardOcr(imageBase64, CardTypeEnum.BANK_CARD.getCode());
		if(MapUtils.isEmpty(bankInfoMap)) {
			return null;
		}
		
		BankcardSaveDTO bankcardSaveDTO = new BankcardSaveDTO();
		bankcardSaveDTO.setBankCardNum(bankInfoMap.get("CardNo"));
		bankcardSaveDTO.setBankName(bankInfoMap.get("BankInfo"));
		//bankcardSaveDTO.set(bankInfoMap.get("ValidDate"));
		return bankcardSaveDTO;
	}
	
	
	public Map<String,String> cardOcr(String imageBase64,String cardType){
		HashMap<String,String> resultMap = new HashMap<String,String>();
		
		if(StringUtils.isBlank(secretId) || StringUtils.isBlank(secretKey) ) {
			MarvelsLogUtil.getInstance().warn("CardOcrService.cardOcr the secretId or secretKey is empty");
			return resultMap;
		}
		
		Credential cred = new Credential(secretId, secretKey);

        HttpProfile httpProfile = new HttpProfile();
        httpProfile.setEndpoint("ocr.tencentcloudapi.com");

        ClientProfile clientProfile = new ClientProfile();
        clientProfile.setHttpProfile(httpProfile);

        if(StringUtils.isBlank(region)) {
        	region = Constants.TEN_REGION;
        }
        OcrClient client = new OcrClient(cred, region, clientProfile);
        
        InterfaceMethodEnum methosdEnum = null;
        StateEnum stateEnum = null;
        try {
        	if(cardType.equalsIgnoreCase(CardTypeEnum.ID_CARD.getCode())) {
        		IDCardOCRRequest req = new IDCardOCRRequest();
        		req.setImageBase64(imageBase64);
        		IDCardOCRResponse resp = client.IDCardOCR(req);
        		resp.toMap(resultMap, "");
        		methosdEnum = InterfaceMethodEnum.TEN_ID_CARD_OCR;
    		}else if(cardType.equalsIgnoreCase(CardTypeEnum.BANK_CARD.getCode())) {
    			BankCardOCRRequest req = new BankCardOCRRequest();
    			req.setImageBase64(imageBase64);
    			BankCardOCRResponse  resp = client.BankCardOCR(req);
        		resp.toMap(resultMap, "");
        		methosdEnum = InterfaceMethodEnum.TEN_BANK_CARD_OCR;
    		}
        	stateEnum = StateEnum.SUCESS;
        }catch(Exception ex) {
        	MarvelsLogUtil.getInstance().error("CardOcrService.cardOcr=====ERROR=====",ex);
        	stateEnum = StateEnum.FAIL;
        }
        MarvelsLogUtil.getInstance().info("CardOcrService.cardOcr resultMap="+JSON.toJSONString(resultMap));
        //记录访问三方接口日志
        try {
        	IntDataQueryLog log = new IntDataQueryLog(methosdEnum.toString(),resultMap.get("RequestId"),Calendar.getInstance().getTime(),stateEnum.toString(),JSON.toJSONString(resultMap),"");
        	intDataQueryLogService.insertDataLog(log);
        }catch(Exception ex) {
        	 MarvelsLogUtil.getInstance().error("CardOcrService.cardOcr save log error",ex);
        }
        
        return resultMap;
	}
}
